#include "mat_app.h"
#include "build.h"	
#include "gen_game_state.h"
#include "mat_mainmenu.h"
#include "mat_ui_popupanimator.h"
#include "mat_mapstate.h"
#include "mat_ui_helper.h"

#ifdef _PLATFORM_IOS
	#ifndef  PRO_VERSION
		#include "inapppurchase/inapppurchasemanager.h"
	#endif
#endif

#include "nextpeer/np_manager.h"
#include "application/game_rms.h"
#include "resman/resman.h"
#include "lang/strman.h"
#include "script/file_list.h"
#include "num/rand.h"
#include "nextpeer/np_manager.h"
#include "script/scripthelper.h"
#include "application/boot_loader.h"
#include "application/credit_state.h"
#include "console/console.h"
#include "font/font_manager.h"
#include "font/font.h"
#include "ui/ui_manager.h"
#include "ui/ui_skin.h"
#include "gameflow/game_flow_manager.h"
#include "gameflow/ui_state.h"
#include "gameflow/ui_popup.h"
#include "vfs/vfs.h"
#include "vfs/archive.h"

#include "util/log.h"				// log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    
#include "util/timer.h"		    
#include <cassert>




using namespace gameflow;

static std::string	ForceLevel;
static void UpdateLoadCB(void* pData);




MT5App::MT5App (	WindowHandler*	pHandler, 
                const			std::string& Config, 
                const			std::string& Log) :
													GameApp(	pHandler, Config, Log),
													m_DebugLoadingCount(0),
                                                    m_IsPause(false)
													
{
    
}

MT5App::~MT5App()
{
	 
}

bool      MT5App::Shutdown()
{            
    NextPeerManager::Instance().ShutDown();
	AdManager::Instance().ShutDown();
    return GameApp::Shutdown();
}

void		MT5App::LoadArchives()
{

#ifdef _PLATFORM_ANDROID
	//AdManager::Instance().RequestBannerAd();
#endif
    
	_LOG(MSG_COMMENT, "LOADING ARCHIVE ------------------------------------------");
	GetHandler()->UpdateOS();    

#if  defined(_PLATFORM_IOS) || defined(_PLATFORM_ANDROID)
	vfs::Archive* pArc = vfs::VFS::Instance().AddArchive("mt5.aac");
#else

//#ifdef  NDEBUG
	vfs::Archive* pArc = vfs::VFS::Instance().AddArchive("mt5.aac");
//#endif

	// use this block for unzipping data from archive
	//if(pArc)
	//	pArc->Unpack("C:\\Users\\2dstar\\Desktop\\data2\\");

#endif
    

#ifndef _PLATFORM_IOS
//#ifdef NDEBUG
	 	
	 
    // use this block to make an archive 
	/*
	vfs::Archive* pOutput = vfs::Archive::CreateArchive();
	script::FileList FL;

	FL.Build("atlas/*.png");
	FL.Build("atlas/*.lua");

	FL.Build("backgrounds/*.jpg");
	FL.Build("decals/*.lua");
	FL.Build("effects/*.p2d");
	FL.Build("effects/*.lua");
	FL.Build("fonts/*.png");     
	FL.Build("fonts/*.lua");     
	FL.Build("fonts/*.ttf");     
	FL.Build("scripts/*.*");
	FL.Build("sounds/*.ogg");
	FL.Build("sounds/*.lua");
	FL.Build("sounds/*.mp3");
	FL.Build("img/*.jpg");
	FL.Build("img/*.lua");
	FL.Build("ui/*.ui");
	FL.Build("ui_img/*.jpg");
	FL.Build("ui_img/*.lua");
	FL.Build("localization/*.*");    	 
	FL.Build("levels/*.lua"); 
	FL.Build("infos/*.lua"); 
	FL.Build("anim/*.sbp"); 
	FL.Build("char/*.lua"); 
	FL.Build("splash/*.jpg"); 

	//custom	
	FL.Build("ui_img/match5_number.png"); 
	FL.Build("ui_img/time_number.png"); 
	FL.Build("ui_img/black_bg.png"); 

	std::vector<std::string> FilesToRead;
	FilesToRead.push_back("img/sprites.lua");
	FilesToRead.push_back("ui_img/sprites.lua");
	FilesToRead.push_back("ui_img/loadingsprites.lua");

	for(int i = 0; i < (int)FilesToRead.size(); i++)
	{
		LuaPlus::LuaState*	pScript = script::ScriptHelper::CreateLuaState();
		if (!script::ScriptHelper::DoFile(*pScript, FilesToRead[i]))
		{
			LuaPlus::LuaState::Destroy( pScript );		
		} 		
		else
		{		
			{	//fix RAII bug
				LuaPlus::LuaObject TileTable = pScript->GetGlobal("Sprites");
				bool ToCopy;			
				for(int i =0; i <TileTable.GetTableCount(); i++)
				{
					LuaPlus::LuaObject Obj = TileTable.GetByIndex(i+1);
					ToCopy = script::ScriptHelper::GetTableBool(Obj,"copy"); 
					if(ToCopy)
						FL.Build(script::ScriptHelper::GetTableString(Obj,"ImageFile"));				

				}
			}  //fix RAII bug

			LuaPlus::LuaState::Destroy( pScript );
		}

	}// for loop
     
	for( int i = 0; i < FL.GetFileC(); i++)
	{
		std::string File =	FL.GetFileName(i);
		pOutput->AddFile(File);
	}
	pOutput->SaveArchive("mt5.aac");
	*/
	                                   
//#endif
#endif
  
}


void		MT5App::OnCreateSplash()
{ 	
	GetHandler()->UpdateOS();
#if defined(WIN32) || defined(_PLATFORM_ANDROID)

	BootLoader	Splash;
	Splash.AddPage("splash/splash.jpg", 
					1, 
					1, 
					2, 
					false,
					"",
					true
					);

	Splash.SetSpeedSkip(true);
	while (!Splash.IsDone())
	{
		Splash.Tick();
		Splash.Render();		
		if(g_pApp && g_pApp->GetHandler())
			g_pApp->GetHandler()->Tick(0);
		//GetHandler()->UpdateOS();
	}	
#endif

	
    
}

void		MT5App::OnBindKeys()
{
	GetHandler()->UpdateOS();
#if !defined(_PLATFORM_IOS) && !defined(_PLATFROM_ANDROID)
	console::Console::Instance().SetBackground("ui_img/black_bg.png");
	console::Console::Instance().PrintLastCommand(false);
	console::Console::Instance().Do("ReloadGame()");		// force it to reload the game scripts
	//console::Console::Instance().BindKey(KEY_ESCAPE, "QuitGame()");
	console::Console::Instance().BindKey(KEY_F2, "CaptureAutoScreenshot()");
	console::Console::Instance().BindKey(KEY_F3, "CaptureMiniScreenshot()");
#endif
  	
}

//GameRMS*	MT5App::CreateRMS()
//{
//	return new GameRMS::;
	//return new FIGVars();
//}

void		MT5App::OnInitFonts()
{
	NextPeerManager::Instance().Init("b8c1be49a3483782fdd85aeaad68dfeb");
	MATUIHelper::ResizeToCurentAspectRatio((ui::UIWidget*)m_pLoadingProgress);

	GetHandler()->UpdateOS();
    
//#ifndef PRO_VERSION
	const std::string BANNER_AD_KEY = "";
	const std::string FULLSCREEN_AD_APPID = "52bcf2c32d42da5ca5d1f9a6";
    const std::string FULLSCREEN_AD_KEY = "daf51606696b41f71160dc84b6dae6198199904d";
	AdManager::Instance().AdInit(BANNER_AD_KEY, FULLSCREEN_AD_APPID, FULLSCREEN_AD_KEY, this);
    
//#endif
    
	// we have done with graphic initialization , time to set loadupdate func
	 ui::UIManager::Instance().SetLoadCB(UpdateLoadCB, this); 


#if defined(_PLATFORM_WIN32)

	const float FONT_WIDTH = 22.0f;
	const float FONT_HEIGHT = 22.0f;

#elif defined(_BUILD_CHINESE)

	const float FONT_WIDTH = 30.0f * 1.4f;
	const float FONT_HEIGHT = 24.375f * 1.3f;

#else

	const float FONT_WIDTH = 30.0f;
	const float FONT_HEIGHT = 24.375f;

#endif

#ifdef _BUILD_CHINESE	
	const std::string FONT_NAME = "fonts/DroidSansFallback.ttf";
#else
	const std::string FONT_NAME = "fonts/BD_Cartoon_Shout.ttf";
#endif

	const float Scale = (float)GetGraphics()->GetScreenWidth() / (float)TEXTURE_WIDTH;
    
	FontManager::Instance().Init("",(int)(FONT_WIDTH * Scale), int(FONT_HEIGHT * Scale));
	Font* pFont = 
	//FontManager::Instance().InitFont("smallfont","Pegasus", 8,16);
	//FontManager::Instance().InitBitmapFont("smallfont", "fonts/smallfont.lua");
	//FontManager::Instance().InitBitmapFont("tinyfont", "fonts/tinyfont.lua");
	//FontManager::Instance().InitBitmapFont("storytext", "fonts/storytext.lua");
	//FontManager::Instance().InitBitmapFont("mediumfont", "fonts/mediumfont.lua");
	//FontManager::Instance().InitBitmapFont("bigfont", "fonts/bigbont.lua");
	//FontManager::Instance().InitBitmapFont("gamefont", "fonts/gamefont.lua");
    
//#ifndef PRO_VERSION

//#else
	//FontManager::Instance().InitBitmapFont("smallfont", "fonts/smallfont.lua");
//#endif
    
	//pFont->SetBorder(true);



#ifdef _PLATFORM_WIN32
	FontManager::Instance().InitFont(	"SmallFont",
										"BD Cartoon Shout",
										//"Droid Sans",
										(int)(FONT_WIDTH * Scale * 0.85f),
										int(FONT_HEIGHT * Scale * 1.25f));

	pFont =
	FontManager::Instance().InitFont(	"GameFont", "GROBOLD",										
										(int)(FONT_WIDTH * Scale  * 0.85f ),
										int(FONT_HEIGHT * Scale * 1.2f ));
	//--------------------------------------------------------------------
#else
	FontManager::Instance().InitFont(	"SmallFont",
										FONT_NAME,
										//"Droid Sans",
										(int)(FONT_WIDTH * Scale * 0.85f),
										int(FONT_HEIGHT * Scale * 1.1f));

#ifdef _BUILD_CHINESE	
#else
	pFont =
	FontManager::Instance().InitFont(	"GameFont",
										"fonts/GROBOLD.ttf",										
										(int)(FONT_WIDTH * Scale * 0.9f ),
										int(FONT_HEIGHT * Scale   * 1.2f));
#endif
#endif



	

    //		console::Console::Instance().SetFont(pFont);
	_LOG(MSG_INIT, "Font manager initialized");
}

void		MT5App::OnCreateStates()
{

	if(!g_pApp->GetRMS()->GetProfile())
	{
#ifdef _BUILD_CHINESE
		g_pApp->GetRMS()->AddProfile("Neo","CHINESE","mt5");
#else
		g_pApp->GetRMS()->AddProfile("Neo","ENGLISH","mt5");
#endif
			
	}

#ifdef WIN32
	GetHandler()->UpdateOS();
#endif
	// register custom components
	//GENBGSmoke::Register();

	

    
    // register custom states
	LuaPlus::LuaState*	pScript = console::Console::Instance().GetScript();
	//audio::AudioManager::Register(pScript);
	GENGameState::Register(pScript);
	//GENVars::Register(pScript);
    //		GameSummary::Register(pScript);
    //		GENMetaState::Register(pScript);
    
    // load savegames
    
	
    
	m_CurrentRate = 0;
#ifdef _PLATFORM_WIN32
	m_TargetRate = 58;
#else
	m_TargetRate = 58;
#endif
    
    
	//GetHandler()->UpdateOS();
	
	
  
//#ifdef WIN32
//	ui::SpriteSet::Instance().SetDeferLoading(false);	// load immediately
//	ui::SpriteSet::Instance().SetClamp(1);	// load immediately		
//#else
	ui::SpriteSet::Instance().SetDeferLoading(true);	// find now, load later
	ui::SpriteSet::Instance().SetClamp(0);	// find now, load later
    res::ResMan::Instance().SetForceSkipInit(true);     // not to load into texture yet
//#endif
    
	
	ui::SpriteSet::Instance().LoadAtlas("atlas/atlas.lua");
	ui::SpriteSet::Instance().AddSet("img/sprites.lua");		
	ui::SpriteSet::Instance().AddSet("effects/sprites.lua");
	ui::SpriteSet::Instance().AddSet("ui_img/sprites.lua");
	ui::SpriteSet::Instance().AddSet("decals/sprites.lua");
	ui::SpriteSet::Instance().AddSet("char/sprites.lua");
	ui::SpriteSet::Instance().AddSet("backgrounds/sprites.lua");

	//ui::SpriteSet::Instance().SetDeferLoading(false);	// load immediately
	//ui::SpriteSet::Instance().SetClamp(1);	// load immediately		
	
	//ui::SpriteSet::Instance().SetDeferLoading(true);	// find now, load later
	//ui::SpriteSet::Instance().SetClamp(0);	// find now, load later
	
    
	// loaded for the bgedit
	//ui::SpriteSet::Instance().AddSet("decals/sprites2.lua");
	//ui::UISkin::Instance().Load("ui/test.skin");
    
    
#ifdef _BUILD_CHINESE
	lang::StrMan::Instance().LoadLangBin("localization/Chinese.bin");
#else
	lang::StrMan::Instance().LoadLangBin("localization/English.bin");
#endif
	 
//#ifdef WIN32
//#else
	ui::SpriteSet::Instance().SetDeferLoading(false);	// find immediately
	ui::SpriteSet::Instance().SetClamp(1);	// load immediately
    res::ResMan::Instance().SetForceSkipInit(false);     // load immediately
    

//#endif 
    
	//ui::UIManager::Instance().RefreshText();
#ifdef WIN32
	GetHandler()->UpdateOS();
#endif
	
	assert(m_pCamera && "No valid camera found");
	gameflow::GameFlowManager&	Game = gameflow::GameFlowManager::Instance();
	Game.SetCamera(m_pCamera);
    
	// load ios setting for tilt etc
	SetupUI();
	
	//ui::UIManager::Instance().RefreshText();
	AUDIO().Init("sounds/soundbank.lua");	
	
	//Game.AddTransitionState("game", new GENGameState(m_pCamera,"ui/in_game.ui","",""));	
	Game.TransitionToState("mainmenu",0.1f);
	//Game.TransitionToState("map",0.5f);
	//Game.TransitionToState("game",0.5f);

	

//#ifdef WIN32
//#else
	res::ResMan::Instance().FlushTexturesExceptUI();
//#endif

	// we are done with you.
	ui::UIManager::Instance().SetLoadCB(NULL,NULL);
	  //		m_IsInitialized = true;
	m_CurrentRate = 0;	// done loading!
	_LOG(MSG_COMMENT ,"Loading Files Count is");
	_LOG(MSG_COMMENT ,m_DebugLoadingCount);
   
    
}

void		MT5App::OnAdFullScreenShow()
{
    gameflow::GameFlowManager::Instance().SetIsPause(true);
	audio::BassAudio::Instance().PauseAll();
    
}

void        MT5App::OnAdFullScreenDismissed()
{
     gameflow::GameFlowManager::Instance().SetIsPause(false);
	audio::BassAudio::Instance().RestartAll();
    
}



// UI Events

void	MT5App::SetupUI()
{
	GameApp::SetupUI();
	
	MATUIPopupAnimatorMgr::Instance();
    
}

static void UpdateLoadCB(void* pData)
{
//#ifndef PLATFORM_IOS
	//((MT5App*)pData)->GetHandler()->UpdateOS();
//#endif
    
	((MT5App*)pData)->UpdateLoadBar(1);
    
#if  defined(_PLATFORM_IOS) || defined(_PLATFORM_ANDROID)
	if(((MT5App*)pData)->m_DebugLoadingCount == 0)
		((MT5App*)pData)->GetHandler()->UpdateOS();
#else
	((MT5App*)pData)->GetHandler()->UpdateOS();
#endif
    
	((MT5App*)pData)->m_DebugLoadingCount++;
    
    if(g_pApp && g_pApp->GetHandler())
        g_pApp->GetHandler()->Tick(0);
}




gameflow::GameState*	MT5App::GetGameStateMainMenu()
{
	return new MATMainMenu(m_pCamera);
}
